#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gmp.h>
#include <time.h>
#include <pthread.h>

mpf_t aBef, b0, aAft, p0;
mpf_t aux1, aux2, aN, aux4,aux5;


//calcula o valor de An
void calcula1(void)
{
    mpf_ui_div(aux1,1,aN);
    mpf_add(aux1,aN,aux1);
    mpf_div_ui(aAft,aux1,2);
    pthread_exit(NULL);
}

//calcula o valor de Bn
void calcula2(void)
{
    mpf_add(aux4,aux2,b0);
    mpf_mul(aux4,aux4,aN);
    mpf_add(aux5,aBef,b0);
    mpf_div(b0,aux4,aux5);
    pthread_exit(NULL);
}

//calcula o valor de Pn
void calcula3(void)
{
    mpf_add(aux1,aux2,aAft);
    mpf_mul(aux4,p0,b0);
    mpf_mul(aux4,aux1,aux4);
    mpf_add(aux1,aux2,b0);
    mpf_div(p0,aux4,aux1);
    pthread_exit(NULL);
}

int main(void){

    pthread_t th1;
    pthread_t th2;
    pthread_t th3;

        int i;
        clock_t start,end;

        mpf_init2(aBef,40000000);
        mpf_init2(b0,40000000);
        mpf_init2(aAft,40000000);
        mpf_init2(p0,40000000);

        mpf_init(aux1);
        mpf_init(aux2);
        mpf_init2(aN,40000000);
        mpf_init2(aux4,40000000);
        mpf_init2(aux5,40000000);
        mpf_set_d(aux1,2);
        mpf_set_d(aux2,1);

    //iniciando a0
        mpf_sqrt(aBef,aux1);

    //iniciando b0
        mpf_set_d(b0,0);

    //iniciando p0
        mpf_add(p0,aux1,aBef); //po=2+raiz2

    start = clock();
        for(i = 0;i < 12;i++){
                mpf_sqrt(aN,aBef);

                pthread_create(&th1, NULL, (void*)calcula1,(void*)NULL);
                pthread_create(&th2, NULL, (void*)calcula2,(void*)NULL);

        pthread_join(th1, NULL);
        pthread_join(th2, NULL);

        pthread_create(&th3, NULL, (void*)calcula3, (void*)NULL);
        pthread_join(th3, NULL);

                mpf_set(aBef,aAft);
        }

    end=clock();
        gmp_printf("%.10000000Ff\n",p0);
    printf("\n--Tempo %ld--\n",(end - start)/CLOCKS_PER_SEC);

        mpf_clear(aux1);
        mpf_clear(aux2);
        mpf_clear(aN);
        mpf_clear(aux4);
        mpf_clear(aBef);
        mpf_clear(aAft);
        mpf_clear(b0);
        mpf_clear(p0);

        pthread_exit(NULL);

        return 0;
}
